/*
 *  Copyright (c) 2022 ZhuHai Jieli Technology Co.,Ltd.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#ifndef    _SPI_INTERFACE_H_
#define _SPI_INTERFACE_H_
#include "typedef.h"

enum spi_mode {
    SPI_MODE_BIDIR_1BIT,    // 支持SPIx(x=0,1,2)，全双工，di接收，do发送
    SPI_MODE_UNIDIR_1BIT,   // 支持SPIx(x=0,1,2)，半双工，do分时发送/接收
    SPI_MODE_UNIDIR_2BIT,   // 支持SPIx(x=0)，半双工，di & do共2bit分时发送/接收
    SPI_MODE_UNIDIR_4BIT,   // 支持SPIx(x=0)，半双工，di & do & d2 & d3共4bit分时发送/接收
};

enum {
    SPI0,
    SPI1,
    SPI2,
    SPI_MAX_HW_NUM,
};

#define SPI_MAX_IO_GROUP            4

struct spi_io {
    u8 cs_pin;
    u8 di_pin;
    u8 do_pin;
    u8 clk_pin;
    u8 d2_pin;
    u8 d3_pin;
};

struct spi_io_mapping {
    u32 num;                                // 可选端口数量
    struct spi_io io[SPI_MAX_IO_GROUP];
};

enum spi_role {
    SPI_ROLE_MASTER,
    SPI_ROLE_SLAVE,
};

struct spi_platform_data {
    u8 port;  // 端口，可选'A', 'B'，'C'
    u8 mode;  // 模式，选项为enum spi_mode中的枚举常量
    u8 role;  // 角色，选项为enum spi_role中的枚举常量
    u32 clk;  // 波特率
};

extern  struct spi_platform_data g_spi0Data;
extern  struct spi_platform_data g_spi1Data;
extern  struct spi_platform_data g_spi2Data;

typedef const int spi_dev;

int spi_open(spi_dev spi);
int spi_dma_recv(spi_dev spi, void *buf, u32 len);
int spi_dma_send(spi_dev spi, const void *buf, u32 len);
void spi_dma_set_addr_for_isr(spi_dev spi, void *buf, u32 len, u8 rw);
void spi_set_ie(spi_dev spi, u8 en);
u8 spi_get_pending(spi_dev spi);
void spi_clear_pending(spi_dev spi);
void spi_set_bit_mode(spi_dev spi, int mode);
u8 spi_recv_byte(spi_dev spi, int *err);
u8 spi_recv_byte_for_isr(spi_dev spi);
int spi_send_byte(spi_dev spi, u8 byte);
void spi_send_byte_for_isr(spi_dev spi, u8 byte);
u8 spi_send_recv_byte(spi_dev spi, u8 byte, int *err);
int spi_set_baud(spi_dev spi, u32 baud);
u32 spi_get_baud(spi_dev spi);
void spi_close(spi_dev spi);

#endif
